﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace ufs.node
{
    public class UploadFileMiddleware : IMiddleware
    {
        NodeConfig _config;

        public UploadFileMiddleware(IOptions<NodeConfig> config)
        {
            _config = config.Value;
        }

        /// <summary>
        /// 获取客户Ip
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public string GetClientUserIp(HttpContext context)
        {
            var ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
            if (string.IsNullOrEmpty(ip))
            {
                ip = context.Connection.RemoteIpAddress.ToString();
            }

            return ip;
        }

        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            NodeResult resultInfo = new NodeResult();

            //ip限制
            var clientIp = GetClientUserIp(context);
            if (!_config.AllowIPs.Contains(clientIp))
            {
                resultInfo.Msg = "ip limit:" + clientIp;
                await context.Response.WriteAsync(resultInfo.ToString());
                return;
            }

            //获取后缀名

            string ext = context.Request.Headers["ext"].ToString();
            //项目文件夹
            string app = context.Request.Headers["app"].ToString();

            try
            {
                var now = DateTime.Now;
                var yy = now.ToString("yyyy");
                var mm = now.ToString("MM");
                var dd = now.ToString("dd");

                var fileName = Guid.NewGuid().ToString("n") + ext;

                var folder = Path.Combine(_config.PhysicalPath, app, yy, mm, dd);
                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }

                var filePath = Path.Combine(folder, fileName);
                using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
                {
                    int blockSize = 1024;
                    var buffer = new byte[blockSize];
                    int count = 0;
                    while ((count = await context.Request.Body.ReadAsync(buffer, 0, blockSize)) > 0)
                    {
                        await fileStream.WriteAsync(buffer, 0, count);
                    }
                }

                var fileUrl = _config.Domain + _config.VirtualPath + "/" + app + "/" + yy + "/" + mm + "/" + dd +
                              "/" + fileName;
                resultInfo.FileUrl = fileUrl;
                resultInfo.Success = true;
                resultInfo.Msg = "ok";
            }
            catch (Exception exp)
            {
                resultInfo.Msg = "【ufsnode】：" + exp.Message + ":" + exp.StackTrace;
            }

            await context.Response.WriteAsync(resultInfo.ToString());
        }
    }
}